package battleOfTheSevenSeas.Client;

import java.io.*;
import java.net.*;
import java.util.ArrayList;


public class Client extends Thread{

	protected static final int PORT = 2012;
	private TheGreatSea tgs = null;
	private DataOutputStream outToServer;
	private BufferedReader inFromServer;
	private Socket connectionSocket = null;
	private String placementSousMarin = "";
	private String hostname = "";
	private Player joueur = null;
	private ArrayList<Player> playerList = new ArrayList<Player>();
	private boolean isSpectator = false;
	private boolean isConnected = false;
	private boolean isConnectedToServer = false;
	private boolean stayOpened = true;

	public Client(String hn, TheGreatSea ts){
		this.tgs = ts;
		tgs.setClient(this);
		hostname = hn;
		while(stayOpened){
			try {

				InetAddress host = InetAddress.getByName(hostname);
				connectionSocket = new Socket(host, 2012);
				outToServer = new DataOutputStream(
						connectionSocket.getOutputStream());
				inFromServer = new BufferedReader(
						new InputStreamReader(connectionSocket.getInputStream()));
				String phraseConnexion = "Connecté à l'adresse " 
						+ connectionSocket.getInetAddress() 
						+ " sur le port : " 
						+ connectionSocket.getPort();
				System.out.println(phraseConnexion);
				tgs.resetClient();
				tgs.refreshText("<System> " + phraseConnexion);
				isConnectedToServer = true;
				isConnected = true;
				tgs.changeMenuState(isConnected);
				tgs.changeServerButtonState(!isConnectedToServer);
				String reponseServeur = "";
				tgs.changeTitle(" [ Connected to Server : " + host.getHostAddress() + " ]");
				while ((reponseServeur = inFromServer.readLine()) != null){
					System.out.println("FROM SERVER: " + reponseServeur);

					// Traitement de la reponse du serveur
					new TraitementCommande(reponseServeur, this);
				}
				throw new IOException();

			}catch (UnknownHostException ue){
				System.err.println("Host Unknown.\n");
			}catch(IOException e){
				tgs.changeMenuState(isConnected);
				isConnectedToServer = false;
				isConnected = false;
				tgs.changeMenuState(isConnected);
				tgs.changeServerButtonState(!isConnectedToServer);
				tgs.refreshText("<System> Connection with server lost");
				tgs.resetTitle();
			}
			while (!isConnectedToServer){
				try {
					sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if (isConnectedToServer()){
					break;
				}
			}
		}
	}

	/**
	 * Ecrit la chaine s sur le DataOutputStream avec un \n et flush
	 * @param s
	 */
	public void writeToServer (String s){
		try {
			outToServer.writeBytes(s + "\n");
			outToServer.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public String getPlacementSousMarin() {
		return placementSousMarin;
	}

	public void setPlacementSousMarin(String placementSousMarin) {
		this.placementSousMarin = placementSousMarin;
	}

	public Player getJoueur() {
		return joueur;
	}

	public void setJoueur(Player joueur) {
		this.joueur = joueur;
	}

	public ArrayList<Player> getPlayerList() {
		return playerList;
	}

	public void setPlayerList(ArrayList<Player> playerList) {
		this.playerList = playerList;
	}

	public DataOutputStream getOutToServer(){
		return this.outToServer;
	}

	public TheGreatSea getTgs(){
		return this.tgs;
	}

	/**
	 * Pour le mode spectateur, permet de mettre a jour les coordonnees
	 * du drone d'un joueur
	 * @param abscisse
	 * @param ordonnee
	 * @param player
	 */
	public void updateDroneCoords(int abscisse, int ordonnee, int player) {
		Player p = playerList.get(player);
		p.setDroneLocation(abscisse, ordonnee);
	}

	public boolean isSpectator() {
		return isSpectator;
	}

	public void setSpectator(boolean isSpectator) {
		this.isSpectator = isSpectator;
	}

	public boolean isConnected() {
		return isConnected;
	}

	public void setConnected(boolean isConnected) {
		this.isConnected = isConnected;
	}

	public boolean isConnectedToServer(){
		return this.isConnectedToServer;
	}
	
	public void setConnectedToServer(boolean isConnect) {
		this.isConnectedToServer = isConnect;
	}

	public void setHostName(String hn){
		this.hostname = hn;
	}

	public void closeClient(){
		this.stayOpened = false;
	}
}